package com.siyu.rehearsal.grpc;

import com.google.protobuf.ByteString;
import com.itf.calc.proto.ItfModelProto;

import java.io.*;
import java.nio.file.*;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class DirectoryWatcher {

    private Path monitoredDir;
    private static final String ASC_EXTENSION = ".asc";
    private static final String NAME_DELIMITER = "-";
    private static final long QUIET_PERIOD_MS = 1000 * 60; // 示例静默期1分钟，根据实际情况调整

    public DirectoryWatcher(Path dir) {
        this.monitoredDir = dir;
    }

    public void checkAndExecuteScript(String pythonScriptPath, Integer qtsize,String outgeoPath) {

        // 计算符合条件的.asc文件数量
        int ascFileCount = 0;
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(monitoredDir, "*.asc")) {
            for (Path path : stream) {
                if (path.getFileName().toString().contains("-")) {
                    ascFileCount++;
                }
            }
        } catch (IOException e) {
            System.err.println("Error reading directory: " + e.getMessage());
        }
        log("asc文件数量: " + ascFileCount);

        // 判断是否满足条件并执行相应操作
        if (ascFileCount >= qtsize) {
            try {
                Thread.sleep(15000); // 等待15秒，15000毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log("文件生成静默期结束且.asc文件数量达标，执行shell脚本  convert_asc_to_geojson.sh...");
            executePythonScript(pythonScriptPath,outgeoPath);

        }
    }

    /**
     * 计算符合特定条件（.asc结尾且包含特定分隔符）的文件数量。
     *
     * @return 符合条件的.asc文件数量
     */
    private int countMatchingASCFiles() {
        File dir = monitoredDir.toFile();
        if (!dir.exists() || !dir.isDirectory()) {
            throw new IllegalArgumentException("监控目录不存在或不是一个目录");
        }

        try {
            log(dir.toPath().toString());
            return (int) Files.list(dir.toPath())
                    .filter(path -> path.getFileName().toString().endsWith(ASC_EXTENSION) && path.getFileName().toString().contains(NAME_DELIMITER))
                    .count();
        } catch (IOException e) {
            throw new RuntimeException("无法读取目录内容", e);
        }
    }

    public static void resultasc(String outputPath, Integer qtsize,String outgeoPath) {
        xiugaigeosh(outputPath);
        Path dir = FileSystems.getDefault().getPath(outputPath);
        DirectoryWatcher watcher = new DirectoryWatcher(dir);

        // 这里仅展示调用逻辑，实际应用中您可能需要结合文件监听机制来不断检查条件
        watcher.checkAndExecuteScript("./convert_asc_to_geojson.sh", qtsize,outgeoPath);
    }

    private void executePythonScript(String scriptName,String outgeoPath) {
        ItfModelProto.FileStreamResponse response = null;
        // 源目录路径
        Path sourceDir = Paths.get("/home/siyu-grpc/cfdata/resultgeo");
        Path targetDir = Paths.get(outgeoPath);
        // 目标ZIP文件路径
        String zipFilePath = "/home/siyu-grpc/cfdata/resultgeo.zip";
        String result = "";
        try {
            // 确保脚本名包含路径，若已在同一目录或环境变量PATH中，则无需此步
            String absoluteScriptPath = new File(scriptName).getAbsolutePath();

            // 检查脚本是否存在且是文件
            if (!new File(absoluteScriptPath).exists() || !new File(absoluteScriptPath).isFile()) {
                System.err.println("脚本文件不存在或不是文件: " + absoluteScriptPath);
            }

            // 修改为调用.sh脚本
            ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", absoluteScriptPath);

            Process p = pb.start();

            p.waitFor(); // 等待脚本执行完成

            //生成resultgeo.zip
            // 首先检查目标目录是否存在，如果不存在则创建
            try (Stream<Path> paths = Files.walk(sourceDir)) {
                // 首先检查目标目录是否存在，如果不存在则创建
                if (!Files.exists(targetDir)) {
                    Files.createDirectories(targetDir);
                }
                // 清空目标目录
                clearDirectory(targetDir);

                // 复制源目录的内容到目标目录

                paths.forEach(source -> {
                    Path relativePath = sourceDir.relativize(source);
                    Path destination = targetDir.resolve(relativePath);
                    try {
                        Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        System.err.println("Failed to copy file: " + source);
                        e.printStackTrace();
                    }
                });
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static String readProcessOutput(InputStream inputStream) throws IOException {
        try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
            return output.lines().collect(Collectors.joining(""));
        }
    }

    /**
     * 日志打印方法，可根据实际情况替换成日志框架。
     *
     * @param message 日志信息
     */
    private void log(String message) {
        System.out.println(message);
    }

    private static void compressDirectory(Path sourceDir, String zipFilePath) throws IOException {
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
            Files.walk(sourceDir)
                    .filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        ZipEntry zipEntry = new ZipEntry(sourceDir.relativize(path).toString());
                        try {
                            zos.putNextEntry(zipEntry);
                            Files.copy(path, zos);
                            zos.closeEntry();
                        } catch (IOException ex) {
                            throw new UncheckedIOException(ex);
                        }
                    });
        }
    }

    public static void xiugaigeosh(String inputDir) {
        String scriptPath = "./convert_asc_to_geojson.sh";
        try {
            // 读取文件内容
            List<String> lines = Files.readAllLines(Paths.get(scriptPath));

            // 修改特定行
            // 修改第四行的input_dir和output_dir
            if (lines.size() >= 4) { // 确保至少有四行
                String fourthLine = lines.get(3);
                if (fourthLine.startsWith("input_dir=")) {
                    fourthLine = fourthLine.replaceFirst("^input_dir=.*", "input_dir=\"" + inputDir + "\"");
                }
                lines.set(3, fourthLine); // 将修改后的行放回列表
            }
            // 写回修改后的内容
            Files.write(Paths.get(scriptPath), lines);

            System.out.println("脚本已成功修改");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Path sourceDir = Paths.get("./shell");
        Path targetDir = Paths.get("./modeldatas");

        try (Stream<Path> paths = Files.walk(sourceDir)) {
            // 首先检查目标目录是否存在，如果不存在则创建
            if (!Files.exists(targetDir)) {
                Files.createDirectories(targetDir);
            }
            // 清空目标目录
            clearDirectory(targetDir);

            // 复制源目录的内容到目标目录

            paths.forEach(source -> {
                Path relativePath = sourceDir.relativize(source);
                Path destination = targetDir.resolve(relativePath);
                try {
                    Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
                } catch (IOException e) {
                    System.err.println("Failed to copy file: " + source);
                    e.printStackTrace();
                }
            });
        } catch (IOException e) {
            System.err.println("Failed to walk the directory: " + sourceDir);
            e.printStackTrace();
        }
    }

    private static void clearDirectory(Path directory) {
        try (Stream<Path> paths = Files.walk(directory)) {
            paths.sorted(Comparator.reverseOrder())
                    .map(Path::toFile)
                    .forEach(File::delete);
        } catch (IOException e) {
            System.err.println("Failed to delete files in directory: " + directory);
            e.printStackTrace();
        }
    }
}

